'use strict';

const Controller = require('egg').Controller;
const _ = require('lodash');

class TopicController extends Controller {
  async noshow(ctx) {
    let page = 1;
    const limit = 100;
    const source = this.ctx.query.source;
    const ignore_type = this.ctx.query.type;
    const sub_tab = this.ctx.query.sub_tab;
    const tab = this.ctx.query.tab;

    // 取已删除的主题
    const query = {};
    if (source) {
      query.source = source;
    }
    if (ignore_type) {
      query.ignore_type = ignore_type;
    }
    if (sub_tab) {
      query.sub_tab = sub_tab;
    }
    if (tab) {
      query.tab = tab;
    }

    const options = {
      skip: (page - 1) * limit,
      limit,
      sort: '-createdAt',
    };

    let topics = await this.ctx.model.Topic.find(query, {
      title: 1,
      original_url: 1,
      createdAt: 1,
      source: 1,
      ignore_type: 1,
      tab: 1,
      _id: 0
    }, options);

    let result = [];
    topics.forEach(t => {
      result.push({
        title: t.title,
        createdAt: t.createdAt.toLocaleString(),
        tab: t.tab,
        source: t.source,
        ignore_type: t.ignore_type,
        original_url: t.original_url
      });
    });

    ctx.body = result;
  }


  async index(ctx) {
    const tab = ctx.query.tab || 'all';
    const mdrender = ctx.query.mdrender !== 'false';

    const query = {};
    if (!tab || tab === 'all') {
      query.tab = {$nin: ['job', 'dev']};
    } else {
      if (tab === 'good') {
        query.good = true;
      } else {
        query.tab = tab;
      }
    }

    let topics = await ctx.service.topicSvc.getTopicsByQuery(query,
      // TODO 修改 eslint 支持在 {} 内使用 ...，栗子：{ sort: '-top -last_reply_at', ...ctx.pagination }
      Object.assign({sort: '-top -last_reply_at'}, ctx.pagination));
    topics = topics.map(topic => {
      topic.content = mdrender ? ctx.helper.markdown(topic.content) : topic.content;
      topic.author = _.pick(topic.author, ['loginname', 'avatar_url']);
      topic.id = topic._id;
      return _.pick(topic, ['id', 'author_id', 'tab', 'content', 'title', 'last_reply_at',
        'good', 'top', 'reply_count', 'visit_count', 'createdAt', 'author']);
    });

    ctx.body = {
      success: true,
      data: topics,
    };
  }

  async create(ctx) {
    // 得到所有的 tab, e.g. ['ask', 'share', ..]
    const allTabs = ctx.app.config.tabs.map(tPair => tPair[0]);

    // TODO: 此处可以优化，将所有使用 egg_validate 的 rules 集中管理，避免即时新建对象
    const RULE_CREATE = {
      title: {
        type: 'string',
        max: 100,
        min: 5,
      },
      content: {
        type: 'string',
      },
      tab: {
        type: 'enum',
        values: allTabs,
      },
    };
    ctx.validate(RULE_CREATE, ctx.request.body);

    const body = ctx.request.body;
    body.content = body.content.replace('\\r\\n', '\r\n');

    // 储存新主题帖
    const topic = await ctx.service.topicSvc.newAndSave(
      body.title,
      body.content,
      body.tab,
      body.original_url,
      ctx.request.user.id
    );

    // 发帖用户增加积分,增加发表主题数量
    let topic_count = 1;
    if (body.tab == 'share') {
      topic_count = 0;
    }
    await ctx.service.userSvc.incrementScoreAndTopicCount(topic.author_id, 3, topic_count);

    // 通知被@的用户
    await ctx.service.atSvc.sendMessageToMentionUsers(
      body.content,
      topic.id,
      ctx.request.user.id
    );

    ctx.body = {
      success: true,
      topic_id: topic.id,
    };
  }


  async show(ctx) {
    ctx.validate({
      id: {
        type: 'string',
        max: 24,
        min: 24,
      },
    }, ctx.params);

    const topic_id = String(ctx.params.id);
    const mdrender = ctx.query.mdrender !== 'false';
    const user = await ctx.service.userSvc.getUserByToken(ctx.query.access_token);

    let [topic, author, replies] = await ctx.service.topicSvc.getFullTopic(topic_id);

    if (!topic) {
      ctx.status = 404;
      ctx.body = {
        success: false,
        error_msg: '此话题不存在或已被删除',
      };
      return;
    }

    // 增加 visit_count
    topic.visit_count += 1;
    // 写入 DB
    await ctx.service.topicSvc.incrementVisitCount(topic_id);

    topic.content = mdrender ? ctx.helper.markdown(topic.content) : topic.content;
    topic.id = topic._id;
    topic = _.pick(topic, ['id', 'author_id', 'tab', 'content', 'title', 'last_reply_at',
      'good', 'top', 'reply_count', 'visit_count', 'createdAt', 'author']);

    topic.author = _.pick(author, ['loginname', 'avatar_url']);

    topic.replies = replies.map(reply => {
      reply.content = mdrender ? ctx.helper.markdown(reply.content) : reply.content;

      reply.author = _.pick(reply.author, ['loginname', 'avatar_url']);
      reply.id = reply._id;
      reply = _.pick(reply, ['id', 'author', 'content', 'ups', 'createdAt', 'reply_id']);
      reply.reply_id = reply.reply_id || null;

      reply.is_uped = !!(reply.ups && user && reply.ups.indexOf(user.id) !== -1);

      return reply;
    });

    topic.is_collect = user ? !!await ctx.service.topicCollectSvc.getTopicCollect(
      user.id,
      topic_id
    ) : false;

    ctx.body = {
      success: true,
      data: topic,
    };
  }

  async update(ctx) {

    const all_tabs = ctx.app.config.tabs.map(tab => {
      return tab[0];
    });

    ctx.validate({
      topic_id: {
        type: 'string',
        max: 24,
        min: 24,
      },
      title: {
        type: 'string',
        max: 100,
        min: 5,
      },
      tab: {type: 'enum', values: all_tabs},
      content: {type: 'string'},
    });

    const body = ctx.request.body;

    let {topic} = await ctx.service.topicSvc.getTopicById(body.topic_id);
    if (!topic) {
      ctx.status = 404;
      ctx.body = {success: false, error_msg: '此话题不存在或已被删除。'};
      return;
    }

    if (topic.author_id != ctx.request.user._id && !ctx.request.is_admin) {
      ctx.status = 403;
      ctx.body = {
        success: false,
        error_msg: '对不起，你不能编辑此话题',
      };
      return;
    }

    delete body.access_token;
    topic = Object.assign(topic, body);
    topic.updatedAt = new Date();


    await topic.save();

    // 通知被 @ 的人
    await ctx.service.atSvc.sendMessageToMentionUsers(
      topic.content,
      topic.id,
      ctx.request.user.id
    );

    ctx.body = {
      success: true,
      topic_id: topic.id,
    };
  }

  /**
   * 展示用户所有原创标签及标签包含文章的数量
   * user_id: 用户id
   * tag_name: 可以按照标签名字模糊搜索
   */
  async listOriginalTags() {
    const {ctx, service} = this;
    const user_id = ctx.request.user.id;
    const tag_name = ctx.request.body.tag_name;
    const tag_size = ctx.request.body.tag_size;

    let result = await service.topicSvc.listOriginalTags(user_id, tag_name);
    ctx.body = {status: 'success', data: result};
  }

  /**
   * 修改原创标签名
   * @param {string} user_id 用户id
   * @param {string} old_name 原标签名
   * @param {string} new_name 新标签名
   */
  async updateOriginalTagName() {
    const {ctx, service} = this;
    const user_id = ctx.user._id;
    const old_name = ctx.request.body.old_name;
    const new_name = ctx.request.body.new_name;

    await service.topicSvc.updateOriginalTagName(user_id, old_name, new_name);

    // 删除标签缓存
    let cache_key = `original_tags:${ctx.user.id}`;
    await this.service.cacheSvc.del(cache_key);
    ctx.body = {status: 'success'};
  }

  /**
   * 删除原创标签
   * id: 标签id,
   * user_id: 用户id
   */
  async removeOriginalTag() {
    const {ctx, service} = this;
    const user_id = ctx.request.user._id;
    const name = ctx.request.body.name;

    await service.topicSvc.removeOriginalTag(user_id, name);

    // 删除标签缓存
    let cache_key = `original_tags:${ctx.user.id}`;
    await this.service.cacheSvc.del(cache_key);

    ctx.body = {status: 'success'};
  }


}

module.exports = TopicController;
